# File name:   MikaelMayer.py
# Author:      Mikael Mayer, EPFL, Lausanne, Switzerland.
# Date:        07 aug 2013
# Description: Answer to the Hunger Game challenge in brilliant.org:
# URL:         https://brilliant.org/competitions/hunger-games/backstory/

# About the algorithm.
# Some basic leaderrship rules applied to Hunger's game.
# 1) A leader's reputation should not depend on others' actions. It should reflects his inner commitment.
# 2) A leader encourages to work those who make efforts by working with them.
# 3) A leader discourages lazy people by not encouraging them.
# And because of the game:
# 4) A leader knows how to make profit where it does not disrupt the total economy.

# Alternating choice to be fair.
oddness = False

def hunt_choices(round_number, current_food, current_reputation, m,  player_reputations):
    global oddness
    pm1 = len(player_reputations)
    # The first 'threshold' players in reputation, we do not hunt with them. We hunt with the other.
    # Note that if pm1 = 3, by default it discourages 2 people having the least reputation
    # and encourages the one having the greatest reputation.
    threshold = (pm1+1) / 2
    if pm1%2 == 1:
        oddness = not oddness
        if oddness and pm1 > 1: #This one is to be able to win if there are only two players left.
            # If pme = 3, one time over two, it will discourage the worst and encourage the two others
            threshold = threshold - 1    

    #Sorts players by increasing reputation, mixing their position
    positions = range(1, pm1+1)
    posrep = sorted(zip(player_reputations, positions), key=lambda p:p[0])

    # Assigns a result depending on the player's position of his reputation.
    newpos = range(1, pm1+1)
    result = [(pos, 's') if i <= threshold else (pos, 'h') for (i, (rep, pos)) in zip(newpos, posrep)]

    # Sort the players back.
    hunt_decisions = [s[1] for s in sorted(result, key=lambda p:p[0])]

    # This algorithm gives a reputation of 1/2
    return hunt_decisions;

def hunt_outcomes(food_earnings):
    # hunt_outcomes is called after all hunts for the round are complete.

    # Add any code you wish to modify your variables based on the outcome of the last round.

    # The variable passed in to hunt_outcomes for your use is:
    #     food_earnings: list of integers, the amount of food earned from the last round's hunts.
    #                    The entries can be negative as it is possible to lose food from a hunt.
    #                    The amount of food you have for the next round will be current_food
    #                    + sum of all entries of food_earnings + award from round_end.
    #                    The list will be in the same order as the decisions you made in that round.

    pass 
    # pass is a python placeholder for if you want to define a function that doesn't have
    # any other code. You should replace pass with your own code if you want to use this
    # function, otherwise leave it to prevent errors caused by an empty function.

def round_end(award, m, number_hunters):
    # round_end is called after all hunts for the round are complete.

    # award - the total amount of food you received due to cooperation in the round.
    # Can be zero if the threshold m was not reached.

    # Add any code you wish to modify your variables based on the cooperation that occurred in
    # the last round.

    # The variables passed in to round_end for your use are:
    #     award: integer, total food bonus (can be zero) you received due to players cooperating
    #            during the last round. The amount of food you have for the next round will be
    #            current_food (including food_earnings from hunt_outcomes this round) + award.
    #     number_hunters: integer, number of times players chose to hunt in the last round.

    pass
